package crew.gwt.client.widgets.util;

import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.TextBox;

public class FloatBox extends Composite implements HasValue<Float> {

	private boolean valueChangeHandlerInitialized;
	
	private final TextBox wrappedTextBox = new TextBox();
	
	public FloatBox() {
		wrappedTextBox.addValueChangeHandler(valueChangeHandler);
		wrappedTextBox.addBlurHandler(blurHandler);
		initWidget(wrappedTextBox);
	}

	private final BlurHandler blurHandler = new BlurHandler() {
		@Override
		public void onBlur(BlurEvent e) {
			e.stopPropagation();
			ValueChangeEvent.fire(wrappedTextBox, wrappedTextBox.getValue() );
		}
	};
	
	public Integer getInteger(){
		try{
			Integer ret = Integer.valueOf(wrappedTextBox.getText());
			return ret;
		}catch(NumberFormatException ex){
			return null;
		}
	}
	
	public void setInteger(Integer value){
		wrappedTextBox.setText((value==null) ? "" : value.toString());
	}

	// ------------------------------ TextBox behavior

	public void setVisibleLength(int i) {
		wrappedTextBox.setVisibleLength(i);
	}
	
	// ------------------------------ HasValue<Float> behavior
	
	/**
	 * The handler added to the widget to fire the value changing.
	 */
	private final ValueChangeHandler<String> valueChangeHandler = new ValueChangeHandler<String>() {
		@Override
		public void onValueChange(ValueChangeEvent<String> event) {
			try{
//				if(wrappedTextBox.getText().isEmpty()) wrappedTextBox.setText("0");
				// Try to parse a number into the box
				Float value = Float.valueOf(event.getValue());
				// fire change event though success
				ValueChangeEvent.fire(FloatBox.this, value);
			}catch(NumberFormatException ex){
				// Parsing failed
				Window.alert("Veuillez saisir un nombre.");
				wrappedTextBox.setFocus(true);
				addStyleName("Form-Element-Wrong");
			}
		}
	};
	
	@Override
	public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Float> handler) {
		// Initialization code
	    if (!valueChangeHandlerInitialized) {
	      valueChangeHandlerInitialized = true;
	      addChangeHandler(new ChangeHandler() {
	        public void onChange(ChangeEvent event) {
	          ValueChangeEvent.fire(FloatBox.this, getValue());
	        }
	      });
	    }
	    return addHandler(handler, ValueChangeEvent.getType());
	}
	public HandlerRegistration addChangeHandler(ChangeHandler handler) {
		return addDomHandler(handler, ChangeEvent.getType());
	}

	@Override
	public Float getValue() {
		try{
			Float ret = Float.valueOf(wrappedTextBox.getText());
			return ret;
		}catch(NumberFormatException ex){
			return null;
		}
	}

	@Override
	public void setValue(Float value) {
		setValue(value, false);
	}

	@Override
	public void setValue(Float value, boolean fireEvents) {
		Float oldValue = getValue();
	    wrappedTextBox.setValue(value.toString());
	    if (fireEvents) {
	      ValueChangeEvent.fireIfNotEqual(this, oldValue, value);
	    }
	}
}
